#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>

#include"juego.h"

void main ()
{
  // Tablero
  char *t[8][8];
  char i, j; // contadores

  // Fichas
  char *jugador, *maquina;
  int ox, oy; //Origen X, Origen Y

  // Opcion de menu
  char menu;

  // Bandera de mensaje
  bool movimiento_valido;

  //Inicializo el tablero
  for (i=0; i<8; i++)
    for (j=0; j<8; j++)
      t[i][j] = "  ";
  
  //Se inicializan con valores por defecto
  menu = 0;
  jugador = "x ";
  maquina = "o ";
  ox = oy = 0;
  movimiento_valido = true;

  system ("clear");
  llenar_tablero (t, maquina, jugador);

  //Se ingresa a las opciones
  do {
    printf("                         \n"
	   " Menu:                   \n"
	   " 1) Jugar                \n"
	   //" 2) Leer instrucciones   \n"
	   //" 3) Ver creditos         \n"
	   " 2) Salir                \n"
	   "                         \n"
	   " Ingresa tu opcion: ");
    
    scanf ("%c", &menu);

    switch (menu)
      {
      case '1':
	do {
	  imprimir_tabla (t);
	  if (movimiento_valido == false)
	    printf("Movimiento inválido\n");
	  
	  if (tomar_ficha (t, jugador, &ox, &oy) == true)
	    if (movimiento_valido = mover_ficha (t, jugador, &ox, &oy) == true)
	      turno_maquina (t, maquina);

	} while (juego_terminado (t, jugador, maquina) == 0);
	break;
	
      default:
	system ("clear");
	break;
      } 

  } while (menu != '2');

  return;
}

/**
 *
 */
void preguntar_posicion (int *x, int *y)
{
  do {
    printf("N° de fila: ");
    scanf ("%d", x);

    printf("N° de columna: ");
    scanf ("%d", y);

    if ( (*y>=0 && *y<8) && (*x>=0 && *x<8) )
      printf ("X: %d, Y: %d \n", *x, *y);
    else
      printf ("La fila y la columna debe estar entre el 0 y el 7 \n");

  } while ( (*y<0 || *y>7) || (*x<0 || *x>7) );
}


/**
 *
 *
 */
bool tomar_ficha (char *t[8][8], char *jugador, int *ox, int *oy)
{
  bool encontrado;
  int x, y;

  x = y = 0;
  encontrado = false;

  do
    {
      printf ("Seleccione la ficha que desea mover \n");
      preguntar_posicion (&x, &y);
      if (t[x][y] == jugador)
	{
	  //t[x][y] = "  ";
	  *ox = x;
	  *oy = y;
	  encontrado = true;
	}
      else
	{
	  imprimir_tabla (t);
	  printf ("No tiene una ficha suya en ese lugar \n\n");
	}
    } while (encontrado == false);

  return encontrado;
}

/**
 *
 *
 */
bool mover_ficha (char *t[8][8], char *jugador, int *ox, int *oy)
{
  int x, y, mover;

  x = y = 0;

  printf ("Seleccione la nueva posicion de la ficha\n");
  preguntar_posicion (&x, &y);
  if (mover = realizar_movimiento (t, jugador, *ox, *oy, x, y, true) != 0)
    return true;
  else
    return false;
}


/**
 *
 *
 */
void llenar_tablero (char *t[8][8], char *ja, char *jb)
{
  char *blanco;
  int f, c; // Filas y Columnas (contador)
  blanco = " ";

  for (f=0; f<8; f++)
    for (c=0; c<8; c++)
      {
	if ( ((f==0 || f==2) && c%2==0) || (f==1 && c%2!=0) )
	  t[f][c] = ja;
	else if ( ((f==5 || f==7) && c%2!=0) || (f==6 && c%2==0) )
	  t[f][c] = jb;
      }
}


/**
 * Valida que la posicion a la que se moverá sea correcta
 *
 * Retorna:
 * 0 = Movimiento invalido
 * 1 = Movimiento valido
 * 2 = Movimiento valido y come pieza
 */
int realizar_movimiento (char *t[8][8], char *jugador, int ox, int oy, int dx, int dy, bool sube)
{
  // El enemigo es el contrario a "jugador"
  char *enemigo;
  // Posicion que deberia tener 'x' dependiendo si sube o baja
  int nx, nx2;
  // Posicion que deberia tener 'y' dependiendo si va a la izquierda o derecha
  int ny, ny2;

  nx = nx2 = ny = ny2 = -1;

  if (strcmp (jugador, "x ") == 0)
    enemigo = "o ";
  else
    enemigo = "x ";

  // Posicion que deberia tener 'x' dependiendo si sube o baja
  nx = (sube) ? ox-1 : ox+1;
  nx2 = (sube) ? ox-2 : ox+2;

  // Posicion que deberia tener 'y' dependiendo si va a la izquierda o derecha
  if (dy == oy+1 || dy == oy+2) ny = oy+1;
  else if (dy == oy-1 || dy == oy-2) ny = oy-1;
  
  if (dy == oy+1 || dy == oy+2) ny2 = oy+2;
  else if (dy == oy-1 || dy == oy-2) ny2 = oy-2;

  if ((dx>=0 && dx<8) && (dy>=0 && dy<8))
    {
      // Si son piezas normales (no reyes)
      if (strcmp (t[ox][oy], "x ") == 0 || strcmp (t[ox][oy], "o ") == 0)
	{ 
	  //Si el salto es de un cuadro en diagonal y ese está vacío
	  if (dx == nx && dy == ny && strcmp (t[dx][dy], "  ") == 0)
	    {
	      t[ox][oy] = "  ";    //Se 'quita' la ficha jugador del origen
	      t[dx][dy] = jugador; //Se pone la ficha jugador en su destino
	      return 1;
	    }
	  //Si el salto es de dos cuadros en diagonal (y ese está vacío) y come pieza
	  else if ((dx == nx2 && dy == ny2 && strcmp (t[dx][dy], "  ") == 0) &&
		   strcmp (t[nx][ny], enemigo) == 0)
	    {
	      t[ox][oy] = "  ";    //Se 'quita' la ficha jugador del origen
	      t[nx][ny] = "  ";    //Se 'come' la ficha enemgio
	      t[dx][dy] = jugador; //Se pone la ficha jugador en su destino
	      return 2;
	    }
	  else
	    return 0;
	}
    }
  else
    return 0;
}


/**
 *
 */
void turno_maquina (char *t[8][8], char *ficha_maquina)
{
  int i;
  int pos[12][2];
  obtener_posiciones_fichas (t, ficha_maquina, pos);
  
  // Intentara comer con cualquier pieza
  for (i=0; i<12; i++)
    {
      //Intenta comer con la pieza hacia un lado y hacia otro
      if (pos[i][0] > -1 && pos[i][1] > -1)
	if (realizar_movimiento (t, ficha_maquina, pos[i][0], pos[i][1], pos[i][0]+2, pos[i][1]+2, false) == 2 || 
	    realizar_movimiento (t, ficha_maquina, pos[i][0], pos[i][1], pos[i][0]+2, pos[i][1]-2, false) == 2)
	  return;
    }

  //Intenta mover con cualquier pieza
  for (i=0; i<12; i++)
    {
      //Intenta comer con la pieza hacia un lado y hacia otro
      if (pos[i][0] > -1 && pos[i][1] > -1)
	if (realizar_movimiento (t, ficha_maquina, pos[i][0], pos[i][1], pos[i][0]+1, pos[i][1]+1, false) == 1 || 
	    realizar_movimiento (t, ficha_maquina, pos[i][0], pos[i][1], pos[i][0]+1, pos[i][1]-1, false) == 1)
	  return;
    }
}

/**
 *
 */
void obtener_posiciones_fichas (char *t[8][8], char *ficha, int pos[12][2])
{
  // Contadores de posicion y contador de fichas (son 12 fichas)
  int i, j, cf;
  
  cf = 0;

  // Se encuentran todas las fichas y se rellenan las posiciones
  for (i=0; i<8; i++)
    for (j=0; j<8; j++)
      if (strcmp (t[i][j], ficha) == 0) 
	{
	  pos[cf][0] = i;
	  pos[cf][1] = j;
	  cf++;
	}

  // Si encuentra menos de 12 fichas, llena las posiciones restantes con -1
  if (cf < 12)
    {
      for (; cf<12; cf++)
	{
	  pos[cf][0] = -1;
	  pos[cf][1] = -1;
	}
    }
}

/**
 *
 * returna:
 * 0 = El juego no termina
 * 1 = El jugador gana
 * 2 = La maquina gana
 */
int juego_terminado (char *t[8][8], char *jugador, char *maquina)
{
  int i, j;
  bool hay_jugador, hay_maquina;

  hay_jugador = hay_maquina = false;

  for (i=0; i<8; i++)
    for (j=0; j<8; j++)
      {
	if (strcmp (t[i][j], jugador))
	  hay_jugador = true;
	
	if (strcmp (t[i][j], maquina))
	  hay_maquina = true;
      }

  if (hay_maquina && hay_jugador)
    return 0;
  else if (!hay_maquina && hay_jugador)
    {
      printf ("Ganaste!!! \n");
      return 1;
    }
  else if (hay_maquina && !hay_jugador)
    {
      printf ("GAME OVER!! \n");
      return 2;
    }
}

 
/**
 *
 */
void imprimir_tabla (char *t[8][8])
{
  system("clear");
  printf("    0   1   2   3   4   5   6   7  \n");
  printf("  |-------------------------------|\n");
  printf("0 | %s| %s| %s| %s| %s| %s| %s| %s|\n", t[0][0], t[0][1], t[0][2], t[0][3], t[0][4], t[0][5], t[0][6], t[0][7]);
  printf("  |---+---+---+---+---+---+---+---|\n");		                    	  	      	  	      
  printf("1 | %s| %s| %s| %s| %s| %s| %s| %s|\n", t[1][0], t[1][1], t[1][2], t[1][3], t[1][4], t[1][5], t[1][6], t[1][7]);
  printf("  |---+---+---+---+---+---+---+---|\n");		                    	  	      	  	      
  printf("2 | %s| %s| %s| %s| %s| %s| %s| %s|\n", t[2][0], t[2][1], t[2][2], t[2][3], t[2][4], t[2][5], t[2][6], t[2][7]);
  printf("  |---+---+---+---+---+---+---+---|\n");		                    	  	      	  	      
  printf("3 | %s| %s| %s| %s| %s| %s| %s| %s|\n", t[3][0], t[3][1], t[3][2], t[3][3], t[3][4], t[3][5], t[3][6], t[3][7]);
  printf("  |---+---+---+---+---+---+---+---|\n");		                    	  	      	  	      
  printf("4 | %s| %s| %s| %s| %s| %s| %s| %s|\n", t[4][0], t[4][1], t[4][2], t[4][3], t[4][4], t[4][5], t[4][6], t[4][7]);
  printf("  |---+---+---+---+---+---+---+---|\n");		                    	  	      	  	      
  printf("5 | %s| %s| %s| %s| %s| %s| %s| %s|\n", t[5][0], t[5][1], t[5][2], t[5][3], t[5][4], t[5][5], t[5][6], t[5][7]);
  printf("  |---+---+---+---+---+---+---+---|\n");		                    	  	      	  	      
  printf("6 | %s| %s| %s| %s| %s| %s| %s| %s|\n", t[6][0], t[6][1], t[6][2], t[6][3], t[6][4], t[6][5], t[6][6], t[6][7]);
  printf("  |---+---+---+---+---+---+---+---|\n");		                    	  	      	  	      
  printf("7 | %s| %s| %s| %s| %s| %s| %s| %s|\n", t[7][0], t[7][1], t[7][2], t[7][3], t[7][4], t[7][5], t[7][6], t[7][7]);
  printf("  |-------------------------------|\n");
}
